'use strict';

function requestAuthenticate(ctx) {
  ctx.set('WWW-Authenticate', 'Bearer realm=\"AUGENBLICK\"');
  ctx.status = 401;
}

function invalidToken(ctx, reason) {
  ctx.set('WWW-Authenticate', 'Bearer realm=\"AUGENBLICK\",' +
    'error=\"invalid_token\",' +
    'error_description=\"' + reason + '\"');
  ctx.status = 401;
}

function insufficientScope(ctx, reason) {
  ctx.set('WWW-Authenticate', 'Bearer realm=\"AUGENBLICK\",' +
    'error=\"insufficient_scope\",' +
    'error_description=\"' + reason + '\"');
  ctx.status = 403;
}

module.exports = () => {
  return async (ctx, next) => {
    let authorization = ctx.get('Authorization');
    if (authorization.indexOf('Bearer ') !== 0) {
      requestAuthenticate(ctx);
      return;
    }

    authorization = authorization.slice(7);
    const token = await ctx.service.authorization.getCodeFromToken(authorization);
    if (!token) {
      invalidToken(ctx, 'Token not found');
      return;
    }

    const detail = await ctx.service.authorization.getDetailFromCode(token.code);
    if (!detail) {
      invalidToken(ctx, 'Token not found');
      return;
    }

    const date = token.created_at;
    if (Date.now() - date > 24 * 60 * 60 * 1000 || Date.now() <= date) {
      invalidToken(ctx, 'Token expired');
      return;
    }

    const scope = JSON.parse(detail.scope);
    if (!scope || scope.indexOf('user_info') === -1) {
      insufficientScope(ctx, 'Scope must contain \'user_info\'');
      return;
    }

    await next();
  };
};
